/*
 * @Author: guojiangang guojiangang@hikvision.com.cn
 * @Date: 2024-02-28 13:48:47
 * @LastEditors: guojiangang guojiangang@hikvision.com.cn
 * @LastEditTime: 2024-03-04 10:00:17
 * @FilePath: \cfase:\leetcode\70.爬楼梯.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/*
 * @lc app=leetcode.cn id=70 lang=javascript
 *
 * [70] 爬楼梯
 *
 * https://leetcode.cn/problems/climbing-stairs/description/
 *
 * algorithms
 * Easy (54.37%)
 * Likes:    3449
 * Dislikes: 0
 * Total Accepted:    1.4M
 * Total Submissions: 2.5M
 * Testcase Example:  '2'
 *
 * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
 * 
 * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢？
 * 
 * 
 * 
 * 示例 1：
 * 
 * 
 * 输入：n = 2
 * 输出：2
 * 解释：有两种方法可以爬到楼顶。
 * 1. 1 阶 + 1 阶
 * 2. 2 阶
 * 
 * 示例 2：
 * 
 * 
 * 输入：n = 3
 * 输出：3
 * 解释：有三种方法可以爬到楼顶。
 * 1. 1 阶 + 1 阶 + 1 阶
 * 2. 1 阶 + 2 阶
 * 3. 2 阶 + 1 阶
 * 
 * 
 * 
 * 
 * 提示：
 * 
 * 
 * 1 <= n <= 45
 * 
 * 
 */

// @lc code=start
/**
 * @param {number} n
 * @return {number}
 */
// 递归，性能最差
// var climbStairs = function(n) {
//   if (!n) return 0
//   function dfs (i) {
//     if (i <= 1) {
//       return 1
//     }
//     return dfs(i - 1) + dfs(i - 2)
//   }
//   return dfs(n)
// };

// // 递归 + 记录返回值 = 记忆化搜索
// var climbStairs = function(n) {
//   if (!n) return 0
//   let memo = Array(n + 1)
//   // 递归
//   function dfs (i) {
//     // 递归边界
//     if (i <= 1) {
//       return 1
//     }
//     // 之前计算过
//     if (memo[i]) {
//       return memo[i]
//     }
//     // 记忆
//     memo[i] = dfs(i - 1) + dfs(i - 2)
//     return memo[i]
//   }
//   return dfs(n)
// };

// 1:1 翻译成递推
// var climbStairs = function(n) {
//   const arr = Array(n + 1)
//   arr[0] = arr[1] = 1
//   for (let i = 2; i <= n; i++) {
//     arr[i] = arr[i - 1] + arr[i-2]
//   }
//   return arr[n]
// }
/*
n为1 => 1
n为2 => 2
n为3 => 3
n为4 => 5
n为5 => 8
n为6 => 13
n为7 => 21
后一个为前两个的相加
*/

// 递推 空间优化
var climbStairs = function(n) {
  let f0 = f1 = 1
  for (let i = 2; i <= n; i++) {
    const curF = f0 + f1;
    f0 = f1
    f1 = curF
  }
  return f1
}

// @lc code=end


// 每次你可以爬 1 或 2 或 3 个台阶，爬n层台阶有多少种方式
/* 
1 => 1
1

2 => 2
1,1
2

3 => 4
1,1,1
1,2
2,1
3

4 => 7
1,1,1,1
1,1,2
1,2,1
2,1,1
2,2
3,1
1,3

5 => 13
1,1,1,1,1
1,1,1,2
1,1,2,1
1,2,1,1
2,1,1,1
2,2,1
2,1,2
1,2,2
3,1,1
1,3,1
1,1,3
2,3
3,2

var climbStairs = function(n) {
  let f0 = f1 = 1, f2 = 2
  for (let i = 3; i <= n; i++) {
    const curF = f0 + f1 + f2;
    f0 = f1
    f1 = f2
    f2 = curF
  }
  return f2
}
 */




